#ifndef _WIFI_CONTROL_H_
#define _WIFI_CONTROL_H_

#include <string>
#include <vector>
#include "modules/module.h"

#include "WifiCredentialDataStore.h"
#include "hw/LedControl.h"

enum NetState{
    NET_STATE_NULL,
    /** define its own wifi network */
    NET_STATE_ROUTER,
    /** join existing wifi network */
    NET_STATE_CLIENT
};

/**
WifiControl
  _ list available wifi networks
  _ store known wifi credentials
  _ connect to known networks
  _ set as router
  _ monitor wifi connection (ping gateway)
  _ ? monitor internet access (ping google.com)
*/
class WifiControl : public module {
public:
    WifiControl(module* coord)
        : m_coordinator(coord)
    {init();}
    
    /** set RPi as router */
    void set_as_router();
    /** set RPi as client */
    void set_as_client();
    /** disable USB bus, saves energy (up to 40%) */
    void wireless_disable();
    /** enable USB bus */
    void wireless_enable();
    /** check if wlan0 is present */
    bool wireless_is_enabled();
    
protected:
    /** list of credential (ESSID/password) extracted from xml file
    path to XML file was retrieved from cordinator */
    std::vector<std::shared_ptr<WifiCredential> > m_credential_list;
    std::vector<std::shared_ptr<WifiCredential> >::iterator m_current_credential;
    
    std::shared_ptr<LedControl> m_led;
    
    void init();
    
    virtual int threadHandler();
    
    /** @return true if in client mode AND connected to a router
    else false */
    bool local_net_status_connected();
    
    /** @return true if one ping to google returned successfuly 
    WARNING this functions takes a lot of time, better to avoid using it */
    bool ping_google();
    
private:
    module* m_coordinator;
    
    void do_router_config();
    /** search for known wifi net and join it if any
    @return true if found a wifi net to join, else false */
    bool do_client_config();
    
    /** load/reload XML file containing wifi credential */
    void loadXML_wifi_credential();
    
    bool m_should_retry_connect;
    
    /** active newtork state */
    //NetState m_current_net_state;
};

#endif
